perm filename BLISS.JLS[UP,DOC]1 blob sn#453175 filedate 1979-06-25 generic text, type T, neo UTF8
BLILIB.DOC                                           January 25, 1978

THE BLISS LIBRARY - AN INTRODUCTION

     A library is  a collection of  REL files of  'utility' programs.
The files  that make  up the library  have special  information which
allows the loader to determine  whether the file should be  loaded or
not.  When a file is loaded in library search mode (/L to the LOADER,
/SEARCH to LINK10, or /LIB to  CCL), the ENTRY block of the  REL file
is examined.   If this  ENTRY block  contains GLOBAL  variables which
have been  referenced but  not defined in  the program  being loaded,
then the file is loaded.  If the file does not contain  definition of
symbols which the loader wants, it is not loaded.

     Since an entire REL file must be loaded if any part of it  is to
be used, library search might not seem very useful.  However, several
REL files may be combined into a single library file by using FUDGE2.
This library file can then be searched in library search mode for all
programs, and only the desired routines will be loaded.

     This  document  contains  a  brief  description  of  the current
contents  of  the  BLISS library  (SYS:BLILIB.REL).   In  the routine
calling sequences below, parameters preceded by a "*" are expected to
be passed "by reference," i.e. the value passed should be the address
of  a  variable   containing  the  indicated  quantity.    All  other
parameters are  expected to be  passed "by value."  Unless explicitly
allowed,  reference parameters  may not  be in  registers.   No error
checking  is  performed  unless  explicitly  noted  in   the  routine
description.



DATE AND TIME CONVERSION

     Five routines are provided for conversion of DEC format date and
time   values.   See   discussion  of   WRITE  below   for  alternate
interpretation of CHNL.

     DATE()
          Returns the current date in DEC format.

     TIME()
          Returns the current time in jiffies since midnight.

     DAYOFWEEK(VAL)
          Returns a  number (0-6) indicating  the day of  the week
          associated with  the DEC format  date in  VAL (0=Sunday,
          6=Saturday).  If .VAL LSS 0 then VAL←DATE() is performed
          first.

     PDATE(CHNL,VAL)
          Writes  the  date  specified  by  VAL  on  the specified
          channel in the format dd mmm yy.  If VAL is less than 0,
          VAL←DATE() is performed first.  Returns .VAL.
BLILIB.DOC                        2                  January 25, 1978

     PTIME(CHNL,VAL)
          Writes the  time indicated  by VAL  (in jiffies)  on the
          specified channel in the form hh:mm:ss.  If VAL  is less
          than 0, VAL←TIME() is performed first.  Returns .VAL.



FLOATING POINT OUTPUT

     These  routines  (basically  borrowed  from  the   SAIL  runtime
package) convert internal floating point numbers to  external format.
They do  extended precision floating  point operations  and therefore
should not lose any precision.  See the discussion of WRITE below for
an alternate interpretation of CHNL.

     FLOUT(CHNL,VAL,BEFORE,AFTER)
          The value VAL is converted to external representation on
          channel  CHNL with  at  least BEFORE  places  before the
          decimal point and AFTER places after the  decimal point.
          If  BEFORE<0,  the number  will  be zero  filled  to the
          specified  width.   If  BEFORE=0,  the  number  will  be
          written  left   justified  using   as  many   spaces  as
          necessary.  Note that BEFORE includes space for the sign
          if VAL is negative.

     EFLOUT(CHNL,VAL,BEFORE,AFTER)
          Similar to  FLOUT except that  the number is  written in
          exponential format,  i.e. "bbb.aaaE+ee" where  there are
          "b" blanks or zeros before the decimal point, "a" places
          after,  and  a  signed  two  digit  exponent.    To  get
          significant  digits   before  the  decimal   point,  use
          SEFLOUT.

     SEFLOUT(CHNL,VAL,BEFORE,AFTER,SCALE)
          Identical  to  EFLOUT  except  that  .SCALE  digits will
          appear before the decimal point.



GENERAL NUMBER OUTPUT

     A routine  for general purpose  output of integers  in arbitrary
bases  (2  to  36  inclusive).  See  discussion  of  WRITE  below for
alternate interpretation of CHNL.

     OUTNUM(CHNL,VAL,BASE,WIDTH)
          The integer VAL is converted to ASCII characters in base
          BASE and written on channel CHNL.  The absolute value of
          WIDTH is the minimum  size of the number  in characters.
          WIDTH<0  will add  leading zeros  if  necessary; WIDTH>0
          adds leading blanks;  WIDTH=0 is equivalent  to WIDTH=1.
          For bases  larger than 10,  the letters "A"  through "Z"
          are used for the extra digits.
BLILIB.DOC                        3                  January 25, 1978

NUMBER INPUT

     The following  routine is a  general format number  scanner.  It
will convert a number from ascii to internal form.

     NUMSCAN(*PTR,BASE,TOG)
          NUMSCAN is used to scan a number off of an ASCII line in
          core.  The number may  be floating point, or  an integer
          in any base (2-10).   PTR is a pointer that  is pointing
          to the first character to be scanned.  If this is  not a
          valid character  for a  number, 0  is returned  (i.e, no
          number = 0).  BASE is the base that the number should be
          treated as.   Only valid  digits for  that base  will be
          treated as numbers.  TOG  is 1 if you expect  the result
          to be floating point, 0 otherwise.  NUMSCAN  will always
          return a number in the expected format.  The  syntax for
          a valid number follows (assuming base 10):

               <d>::= 0!1!2!3!4!5!6!7!8!9
               <s>::= +!-!<e>
               <e>::=
               <i>::= <d> ! <i><d>
               <si>::= <i> ! <s><i>
               <n>::= <si> ! <si>.<i> ! <si>.<i>E<si>

          Where "." and  "E" have their usual  interpretations for
          floating point numbers.  Note that no spaces  may appear
          imbedded in  the number.  Warning:  you may  get strange
          results  if  a  floating  point  number  is  found while
          looking for a non-decimal number.



FILE NAME SCANNING

     A facility for converting  an ASCII string of characters  into a
filename, extension and ppn is available.

     FILESCAN(*PTR,*BLOCK)
          PTR is the address of a byte pointer or the address of a
          routine, BLOCK is the address of a five word block (word
          0  holds   device  name,  words   1-4  are   a  standard
          LOOKUP/ENTER block).  If PTR is a byte pointer it should
          be  adjusted  so  that  a  SCANI  will  read  the  first
          character of the file specification(i.e. pointing to the
          character before the  file spec.).  The pointer  will be
          advanced and left pointing at the character that stopped
          the  scan   (Break  characters  include   <null>,  <cr>,
          <altmode>,  <←>,  </>, <(>,  and  <,>).  If  PTR  is the
          address  of  a  routine  it  should  be  a parameterless
          routine which returns the next character to be scanned.

          Only fields actually  present in the string  are entered
          in the block allowing the user to specify default values
          by storing  them in the  block before  calling FILESCAN.
          The right half of the value of FILESCAN is 1 (true) if a
BLILIB.DOC                        4                  January 25, 1978

          valid file specification was scanned and logically false
          if errors were found.  The errors are:
                    2 - colon seen but no device name found
                    4 - invalid CMU PPN format
                    6 - CMUDEC UUO failed
                    8 - invalid octal PPN

          The  left half  of the  value of  FILESCAN  contains the
          break character which stopped the scan.



PPN CONVERSION

     The two routines in this package perform conversion  between CMU
user id's  and DEC  format octal  PPN's using  the CMUDEC  and DECCMU
UUO's.

     CMUDEC(PTR)
          PTR is the address  of a two word buffer  containing the
          CMU  user id  left justified  in ASCII  characters.  The
          value returned is the  octal PPN or 0 if  the conversion
          UUO failed (invalid user id format).

     DECCMU(PPN,*PTR)
          PPN  is  the octal  PPN  to be  converted.   PTR  is the
          address of a two word buffer into which the CMU  user id
          will be placed (in left justified ASCII).  The  value of
          DECCMU  is  1 if  the  conversion succeded  or  0  if it
          failed.



I/O

     A slightly  modified version of  Joe Newcomer's DYIO  package is
included in the library.  In the following routine  descriptions CHNL
means the channel number (LEQ #17 ... no error checking).  A negative
channel number will do  Teletype io with TTCALL's.   Unless otherwise
noted all routines return true (odd) for success and false (even) for
failure.  The external  location IOSTATUS[.CHNL] always  contains the
current file status bits for a channel.

     GETCHAN()
          Returns the number of a free channel or -1 if no channel
          is free.

     BUFFERS(CHNL,NUMBER,INPUT,WHERE)
          BUFFERS helps set up buffers for I/O if you do  not want
          the monitor  to do it  for you.  (e.g.   if you  want to
          allocate  space  for   buffers  from  a   dynamic  space
          package).  INPUT is true to set up input  buffers, false
          for output buffers.   If NUMBER is  0, the value  of the
          routine  is  the  data  size  for  each  buffer  on this
          channel.  (Note: actual  buffer size  must be  two words
          larger).   If  NUMBER  is non-zero,  WHERE  must  be the
BLILIB.DOC                        5                  January 25, 1978

          address at which the buffer ring is to start.  (If WHERE
          is 0 then the buffer ring will be set up at  the current
          value of .JBFF and  .JBFF will be updated to  point past
          the new buffers.) A ring of NUMBER standard buffers will
          be initialized.  The value of the routine is undefined.

     OPEN(CHNL,STATUS,LDEV,BUFS)
          OPENs the specified channel.  STATUS, LDEV, and BUFS are
          the  parameters required  by  the OPEN  UUO  (see PDP-10
          Handbook).  In particular BUFS contains the addresses of
          the three word buffer headers for the channel (output in
          left half, input in right half).

          BEWARE!  If  one of the  buffer headers is  absent, that
          halfword MUST BE ZERO.  However, undotted names in BLISS
          are  considered  by the  compiler  to  have byte-pointer
          parts in  their left halves.   Thus, the correct  way to
          specify  an  input  buffer header  IBUF,  and  no output
          buffer  header,  as  the  last  parameter  BUFS,  is not
          "IBUF", but "IBUF<0,0>".

          Also, if you use any  channel I/O, don't forget to  do a
          RESET UUO as the  first thing in your program.   A RESET
          is a CALLI(0,0); see the PDP-10 handbook.

     LOOKUP(CHNL,*LOOKUPBLOCK)
          Performs LOOKUP on specified channel.   LOOKUPBLOCK must
          be the address of a four-word control block as described
          in the PDP-10 Handbook.

     ENTER(CHNL,*ENTERBLOCK)
          Like LOOKUP.

     READ(CHNL)
          Returns:
              -1 for end of file
              -2 for I/O error
              otherwise: the next byte from file


          Note: When  reading binary files,  the values -1  and -2
          may be  data rather than  error conditions.  If  this is
          possible  the  user should  check  IOSTATUS  (indexed by
          channel  number) for  the status  bits for  the channel.
          See PDP-10 Handbook for the meaning of these bits.

     WRITE(CHNL,CHAR)
          Outputs  CHAR on  specified channel.   If CHNL  GTR #17,
          perform (.CHNL)(.CHAR).  This is most useful for writing
          numbers to  core locations rather  than to a  file; just
          pass a routine address  to OUTNUM or FLOUT instead  of a
          channel number.
BLILIB.DOC                        6                  January 25, 1978

     WRITEMSG(CHNL,PTR)
          Writes  the  ASCIZ  string  beginning  with   the  first
          character of the word addressed by PTR on  the specified
          channel.  If the  size field (<24,6>)  of PTR is  not 7,
          then  <36,7>  is  used  to  read  characters  from  PTR;
          otherwise, the  pointer is  assumed to  be such  that an
          ILDB  will  pick  up  the  first  character.   Alternate
          interpretation of CHNL as in WRITE applies here as well.

     PURGEOUT(CHNL)
          Dumps output buffer on specified channel.

     CLOSE(CHNL)
          Executes  CLOSE  and  RELEASE  operations  on  specified
          channel (see PDP-10 Handbook).

     CLOSEF(CHNL,BITS)
          Executes the CLOSE  operation on the  specified channel.
          The value of BITS will be used as the CLOSE inhibit bits
          (see PDP-10 Handbook).

     OUTMSG(TEXT)
          Text is the address of  an ASCIZ string to be  output on
          the Teletype.  Value is undefined.

     BUFHDR(CHAN)
          BUFHDR  returns the  XWD  OBUF,IBUF passed  as  the last
          parameter  to OPEN.   This, like  SAIL's CHNCDB,  is for
          those who wish to  use BLILIB's OPEN, LOOKUP,  etc., but
          want to avoid using READ  and WRITE.  If CHAN is  not in
          the range [0, 17], the value returned is 0.



MORE I/O

     These routines provide less commonly needed I/O functions and so
they  are included  in  a separate  module.  These  routines  are not
loaded if none of them are used.

     LREAD(CHNL)
          This  routine is  just like  READ above  except  that it
          should be used only for ASCII mode files.  The left half
          of the return value will be 1 if the character just read
          is the first character of an SOS line  number, otherwise
          the left  half is  0.  The right  half is  the character
          read from the file.  Negative channel numbers and return
          values are as described under READ.

     READLINE(CHNL,*BUFFER,*LINENUMBER)
          This routine reads  a "line" from the  specified channel
          into the buffer addressed by BUFFER.  A line  is defined
          as  everything up  to  and including  the  next linefeed
          character  (ASCII  12).  If  the  line has  an  SOS line
          number, the line number word will be stored in  the word
          addressed  by LINENUMBER.   The tab  following  the line
BLILIB.DOC                        7                  January 25, 1978

          number is lost.  If the value 0 is passed instead of the
          address of a variable to hold the line number,  the line
          number is discarded (Cf. Newell's Bucket).  The value of
          the  routine  is  the number  of  text  characters read.
          READLINE works  for negative  channels (TTY  input), but
          the only break character recognized is linefeed.

     RENAME(CHNL,*RENAMEBLOCK)
          Change  the name  of the  last file  read or  written on
          CHNL.   This  function  closes  the  file  but  does not
          release  the channel,  i.e. no  further READ,  WRITE, or
          RENAME  functions may  be performed,  but  LOOKUP and/or
          ENTER may be  called without OPENing the  channel again.
          If the name  (first word) in  the RENAMEBLOCK is  0, the
          file is deleted.

     PURGEOUT(CHNL)
          Dumps output buffer on specified channel.

     CLOSEF(CHNL,BITS)
          Executes the CLOSE  operation on the  specified channel.
          The value of BITS will be used as the CLOSE inhibit bits
          (see PDP-10 Handbook).

     DUMPIN(CHNL,LISTADDRESS)
          Execute a  dump mode input  operation on CHNL  using the
          the command list addressed by LISTADDRESS.  Note  that a
          dump-mode command list is of the form <cmd>, <cmd>, ...,
          0,  where <cmd>  is a  negative word-count  in  the left
          half, and the  destination address-1 in the  right half.
          Most users'  command lists contain  only one  <cmd>, for
          only one read or write.  These command lists must  be in
          the low segment.

     DUMPOUT(CHNL,LISTADDRESS)
          Like DUMPIN except output is done.

     GETSTS(CHNL)
          Returns the file status bits for CHNL.

     SETSTS(CHNL,BITS)
          Sets the  file status  bits for  the channel.   Does not
          change buffer pointers, size, or count.

     USETO(CHNL,BLKNUM)
          Execute a  USETO operation on  CHNL.  This  operation is
          meaningful only for DSK and DTA files.

     USETI(CHNL,BLKNUM)
          Execute a  USETI operation on  CHNL.  This  operation is
          meaningful only for DSK and DTA files.
BLILIB.DOC                        8                  January 25, 1978

COMPLEX MESSAGE OUTPUT

     This routine allows the building of complex output  messages and
contains several useful forms of output conversion.

     MSGSCAN(CHNL,PARMS,PATTERNPTR)
          MSGSCAN   takes   a  pattern   string   and  substitutes
          parameters with various  kinds of conversions  at places
          marked  by  the  character "%".   The  "%"  character is
          followed  by  one  or more  characters  to  indicate the
          conversion to  be done  on the  corresponding parameter.
          The pattern string may be in ASCIZ or SIXBIT.   The type
          of pattern string is determined by examining the pointer
          passed  in  the  PATTERNPTR  position.   A   size  field
          (<24,6>) of 7 indicates ASCIZ, 6 indicates  SIXBIT.  Any
          other  size  field  causes  the  pointer  <36,7>  to  be
          assumed.

          As  many  parameters as  desired  may be  passed  in the
          position  labeled  PARMS in  the  calling  sequence, but
          there must  be a  one-to-one correspondence  between the
          parameters  and  the  number of  "%"  characters  in the
          pattern.  The exceptions to the one-to-one rule  are the
          sequence "%%"  which outputs the  "%" character  and the
          sequence "%Z" which terminates SIXBIT patterns.  Some of
          the conversions take an additional character  for format
          control.   The  following  conversions  are implemented.
          Upper  and  lower  case  letters  are  equivalent.   All
          characters not mentioned are currently no-ops but do use
          up a parameter.

             D   minimum width decimal conversion of parameter

             O   minimum width octal conversion of parameter

             7   parameter is 1-to-5 characters in  left justified
                 ascii OR 1 character right justified ASCII

             6   parameter  is  six  SIXBIT  characters  but blank
                 characters are suppressed

             S   like 6 but blanks are not suppressed

             5   parameter is in (PDP-10) RADIX 50 format

             A   parameter is a pointer to an ASCIZ string; <36,7>
                 assumed iff the size field is not 7

             P   parameter is a DEC format PPN to be converted for
                 output; "[]" are not included

             N   parameter is the  address of a FILESCAN  block to
                 be  output;  device  will  be  output  iff  it is
                 neither 0 nor 'DSK'

             Fx  parameter is  a floating point  number to  be put
BLILIB.DOC                        9                  January 25, 1978

                 out by  FLOUT; "x" is  a single  digit specifying
                 the AFTER parameter

             Ex  like F except EFLOUT is used

             Tx  parameter is a time (in jiffys) to be output; "x"
                 specifies format
                 x=0 --> hh:mm:ss
                 x=1 --> hh:mm
                 x=2 --> hh:mm in 12 hour form followed by  one of
                 (AM, PM, N, M)

             C   parameter is  a DEC  format calendar  date, calls
                 PDATE

             W   parameter is passed to DAYOFWEEK  and appropriate
                 day is output

             V   parameter is printed in DEC Version  format, e.g.
                 22A(204)-3

             %   output  the   character  "%";  no   parameter  is
                 consumed

             Z   SIXBIT patterns only, indicates end of pattern



FILE SELECTION

     At long  last useable, semi-high  level file  selection routines
have been written for BLISS.

     WANTREAD(*CHNL,MODE,BUFS,PTR,*BLOCK,*PPN)
          The effect of  this routine is to  find a file  to read.
          In the simplest  case, PTR, BLOCK,  and PPN are  0, CHNL
          contains -1, and the  terminal is prompted for  the name
          of  an  input  file (including  device  and  ppn).  This
          dialog is repeated  until a file is  successfully looked
          up.

          CHNL is  the address of  a variable holding  the channel
          number;  if  this number  is  in the  range  0-#17, that
          channel is  used, otherwise a  free channel  is selected
          using GETCHAN() and returned in the variable.   MODE and
          BUFS are as described for OPEN above; the BEWARE comment
          applies here, too.

          PTR may be a byte pointer to a string to be  scanned for
          a  first  try  at  finding  a  file  (SCANI  gets  first
          character) or 0.  BLOCK may  be the address of a  5 word
          block of  storage in FILESCAN  format which  may contain
          default values for device, name, extension, and ppn.  If
          the combination of the words in BLOCK and the  string at
          PTR  are  sufficient  to  find  a  file,  a   LOOKUP  is
          attempted.  If this LOOKUP  is not successful or  if the
BLILIB.DOC                       10                  January 25, 1978

          data was insufficient,  the terminal is prompted  for an
          "Input File: "  and  input is  read  from  the terminal.
          After terminal  input, only  the default  extension from
          BLOCK  is remembered;  other fields  are zeroed  and the
          device defaults to "DSK".

          If an address is supplied for BLOCK, the 5 words at that
          address will contain the device, name, and  extension of
          the file found on return.  The other words  will contain
          information in the  format specified for the  LOOKUP UUO
          in the PDP-10 Reference Handbook.

          Since the  LOOKUP UUO  overwrites the  ppn field  of the
          lookup block  with the file  size, the PPN  parameter is
          provided  to return  the ppn  of the  file found  to the
          user.  If PPN is non zero, the ppn of the  file actually
          found will be returned in the word addressed by PPN.

          The  value of  WANTREAD  is normally  FALSE  (even).  If
          there are no channels  available, or if the  request was
          aborted by the user  typing <return> to the  request for
          an input file, the  value of WANTREAD is TRUE  (odd) and
          no file is looked up.

     WANTWRITE(*CHNL,MODE,BUFS,PTR,*BLOCK,WARN)
          WANTWRITE is just  like WANTREAD except that  the effect
          is to open  a file for  output.  All parameters  are the
          same  except WARN.   If WARN  is TRUE  (odd),  a warning
          (requiring user response)  will be generated  if writing
          the file would delete an already existing file.   If the
          file specified is  protected against writing,  a message
          will be given and a new file name will be requested from
          the terminal.



DYNAMIC SPACE ALLOCATION

     A simple  dynamic space  allocation package  is included  in the
library.  No headers or system  information is kept in the  blocks of
space allocated.  The  user is responsible  for keeping track  of the
address and size of the storage he allocates.

     INITSPACE()
          INITSPACE  will initialize  (or reinitialize)  the space
          allocation  tables.   Space  is  allocated  in  the  low
          segment  beginning at  the  end of  the  user's program.
          JOBFF is  assumed to  contain the  address of  the first
          free word when INITSPACE  is first called (this  can and
          should be  accomplished by executing  a RESET  UUO, i.e.
          CALLI 0,0).   Subsequent calls  on initspace  will clear
          the  free  space  lists  and  begin  allocating  at  the
          beginning of the space.
BLILIB.DOC                       11                  January 25, 1978

     GETSPACE(SIZE)
          Returns  the address  of the  first of  a block  of SIZE
          words. All blocks are zeroed before being allocated.

     RELSPACE(ADDRESS,SIZE)
          Releases the block  of SIZE words beginning  at ADDRESS.
          Value is undefined.

     GARBAGECOLLECT()
          This routine may  be called at  any time to  compact the
          space on the free space lists.  This routine is not very
          efficient and should not be called frequently.  An ideal
          time is  just after  a large number  of cells  have been
          released.



SCIENTIFIC SUBROUTINE PACKAGE

     Several useful  (?) routines have  been stolen from  the FORTRAN
library and  made BLISS compatible.   All routines accept  and return
floating point values.  Since  there is no runtime error  support, no
complaint is made for invalid arguments.

     SQRT(X)
          Computes the square root  of X.  Returns -1.0 for  X LSS
          0.0.

     SIN(X) and COS(X)
          Computes the indicated  trigonometric function of  X.  X
          is assumed to be in radians.

     LOG(X)
          Computes the natural (base e) logarithm of X.  If  X LEQ
          0.0,  the  most negative  floating  point  number (about
          -1.7E+38) is returned.

     EXP(X)
          Computes the exponential function of X, i.e. e raised to
          the  X  power.  Returns  0.0  for X  LSS  -89.415986 and
          largest number (about 1.7E+38) for X GTR 88.029691.



PSEUDO-TELETYPE I/O

     Routines  for  communicating with  pseudo-teletypes  (see PDP-10
Handbook).  These routines use the library I/O routines  described on
page 4.

     GETPTY(*CHNL,*PTYNUM)
          CHNL is a pointer to a word containing a channel number.
          PTYNUM is a pointer  to a word containing a  PTY number.
          If either  of these  point to a  word containing  -1, an
          arbitrary choice is made from available  resources.  The
          routine inits the PTY on the channel.  The PTY number is
BLILIB.DOC                       12                  January 25, 1978

          returned in the word  pointed to by PTYNUM,  the channel
          number in  the word  pointed to by  CHNL.  Returns  1 if
          successful.  Error returns are:
                    0 - No channel available
                    2 - Channel specified already in use
                    4 - PTY specified already in use
                    6 - No PTY available
                    8 - Cannot open PTY

     PTYLOG(CHNL,*JOBNUM,*PPN,*PASS)
          Logs on a job on  the PTY inited on channel  CHNL.  Uses
          the ASCIZ strings pointed to by PPN and PASS as  ppn and
          password.  If  the ppn  is the  same as  the controlling
          job, no  password is needed  and the PASS  oparameter is
          ignored.   Returns the  jobnumber assigned  in  the word
          pointed  to  by  JOBNUM.   Returns  1  if  successful, 0
          otherwise.

     PTYATT(CHNL,JOBNUM,*PPN,*PASS)
          Attaches the PTY inited on CHNL to job JOBNUM.  Uses the
          ASCIZ  string pointed  to  by PPN  and PASS  as  ppn and
          password.  Returns 1 if successful, 0 otherwise.

     PTYDET(CHNL)
          Detaches the job on the PTY inited on CHNL.

     PTYKJOB(CHNL)
          Kills the job on the  PTY inited on CHNL.  Returns  1 if
          successful, 0 otherwise.

     PTYRELEASE(CHNL)
          Kills the  job on the  PTY inited on  CHNL, if  any.  It
          deassigns  the PTY  if it  was assigned  internally, and
          closes  the  channel.    Returns  1  if   successful,  0
          otherwise.

     PTYMONMOD(CHNL)
          Sends ↑C↑C to the PTY inited on CHNL.

     INITPTYS()
          Initializes the PTY routines.

     PTYOC(CHNL,CHAR)
          Sends CHAR to the PTY inited on CHNL.

     PTYOSTR(CHNL,*STR)
          Sends  the ASCIZ  string pointed  to by  STR to  the PTY
          inited on CHNL.

     PTYINC(CHNL)
          Reads a character from the PTY inited on  CHNL.  Returns
          the  character  if   successful,  -1  if   no  character
          available, or -2 if there were I/O errors.
BLILIB.DOC                       13                  January 25, 1978

     PTYINW(CHNL,MAXWAIT)
          Waits up  to MAXWAIT  ms. for a  character from  the PTY
          inited on CHNL.  Returns the same as PTYINC.

     PTYWAIT(CHNL,MAXWAIT,*STR)
          Waits up to MAXWAIT ms. for the ASCIZ string  pointed to
          by STR  to appear in  the input from  the PTY  inited on
          CHNL.   The string  may be  a maximum  of  20 characters
          long.  Returns 1 for success, 0 otherwise.

     PTYCLRBUF(CHNL)
          Clears  the  input buffer  of  the PTY  inited  on CHNL.
          Note: more input can appear after PTYCLRBUF is done.

     PTYRESPONSE(CHNL)
          Returns 1 if there is input from the PTY inited  on CHNL
          waiting to be  read, 0 otherwise.  Note:  if PTYRESPONSE
          returns 0, it may still be the case that there  is input
          in  the PTY  handlers  buffers.  To  be sure  also  do a
          PTYINC.

     PTYHIBER(CHNL,MAXWAIT)
          Puts  the job  to sleep  until either  MAXWAIT  ms. have
          passed, or  there is activity  on CHNL.   Note, activity
          from any PTY inited will wake a PTYHIBER so  be careful.
          Whereever the MAXWAIT parameter  appears, if it is  0 it
          means wait indefinitely.



SPOOLING

     It is possible to enter files in the printer queue under program
control.  The following routine interacts with the spooler to do just
that.

     SPOOL(*BLOCK,COPIES,DELETE)
          BLOCK is  the address of  a block of  five words  in the
          format provided by  FILESCAN (page 3).  The  device name
          must be provided  and must be  a disk type  device.  The
          number  of copies  is  forced to  be between  1  and 10,
          inclusive.  If DELETE is  odd, the file will  be deleted
          after printing.  SPOOL returns 1 if the file was spooled
          successfully, 0 otherwise.   SPOOL uses and  expects the
          user to use the library I/O routines (page 4).



RANDOM NUMBER GENERATORS

     The random  number generators  in BLILIB  were written  by Amund
Lunde for Poomas.  They  have been modifed somewhat.   In particular,
they do no error checking; garbage in, garbage out.

     A  random  number  stream is  a  variable  containing successive
values of  a sequence of  integers.  Each member  of the  sequence is
BLILIB.DOC                       14                  January 25, 1978

obtained  from the  previous by  one basic  drawing according  to the
linear congruential method:

          U ← (5↑15 * .U + 7261067085) MOD 2↑35

     where ↑ is the exponentiation operator.

     For further information see:
          Knuth, D. E.
          The Art of Computer Programming
          Volume 2
          Semi-Numerical Algorithms
          Addison Wesley 1969

     By theorem A,  page 15 of Knuth,  the sequence obtained  in this
way has  a period  of 2↑35.   Furthermore, by  the spectral  test the
multiplier  5↑15 and  modulus  2↑35 have  very  desirable statistical
properties.  See Knuth, page  88.  The addend is chosen  by criterion
(41), Knuth page 78.

     A random floating point number in [0.0,1.0) is obtained from the
above by shifting it 8 bits right, and forcing the sign  and exponent
to octal  200.  These  numbers are  used by  all the  routines below.
They are unnormalized.  The results of the routines below  are either
integer, or normalized floating point.

     Each of  the routines  drawing from  distributions has  a random
number stream as one  of its parameters.  The user  should initialize
the stream by assigning some integer value to it.  Each  routine will
advance its parameter stream by performing one or more  drawings from
it,  according  to  the  needs of  that  routine.   Hence  the stream
parameter has to be passed  by reference.  In the definitions  of the
routines below, this parameter is U.

     The following routines are implemented:

     RANDINT(A,B,*U)

          A = integer, lower bound.
          B = integer, upper bound.

          The value of RANDINT  is one of the integers  in [.A,.B]
          with equal probability.  .A < .B is assumed.

     UNIFORM(A,B,*U)

          A = real, lower bound.
          B = real, upper bound.

          The  values  of  UNIFORM  are  real   numbers  uniformly
          distributed in [.A,.B).  .A < .B is assumed.

     NORMAL(A,B,*U)

          A = real, mean.
          B = real, standard deviation.
BLILIB.DOC                       15                  January 25, 1978

          The values of  NORMAL are real and  normally distributed
          with the above  parameters.  The normal  distribution is
          obtained as described in:

               Abramowitz, M. and Stegun, I. A. (Eds.)
               Handbook of Mathematical Functions
               National Bureau of Standards
               Applied Mathematics Series No. 55
               PP. 952-953

     FASTNORMAL(A,B,*U)

          A = real, mean.
          B = real, standard deviation.

          The  values   of  FASTNORMAL   are  real   and  normally
          distributed  with  the  above  parameters.    Note  that
          FASTNORMAL uses the  sum of four drawings  from UNIFORM,
          rather than  the formula  used by  NORMAL.  It  is about
          twice  as  fast,  but less  accurate  than  NORMAL.  The
          algorithm is:

                .A + .B * ((.U1 + .U2 + .U3 + .U4) - 2.0) * SQRT(3.0)

          where the Ui are uniform in [0,1).

     NEGEXP(A,*U)

          A = real, inverse of mean.

          The  values  of  NEGEXP  are  real,  distributed  as the
          negative exponential with  mean 1/.A.  This is  the same
          as  the distribution  of  "waiting times"  in  a Poisson
          process with the expected number of arrivals equal to .A
          per time  unit.  The  value is  obtained by  the formula
          -Log(.U)/.A where .U is uniform in [0,1).

     POISSON(A,*U)

          A = real, distribution parameter.

          The values  of POISSON are  integer, distributed  as the
          Poisson distribution.   The value, N,  is obtained  by n
          drawings,  uniform in  [0,1),  where n  is  the smallest
          integer such that:

                1.0 * U1 * U2 * ... * Un < exp(-.A)

               if .A > 20.0.
               If .A < 0.0 then NORMAL(.A,sqrt(.A),.U) is used.

     ERLANG(A,B,*U)

          A = real, inverse mean.
          B = real, described below.
BLILIB.DOC                       16                  January 25, 1978

          The values of ERLANG are real, distributed as the Erlang
          distribution  with  mean  1/.A,  and  standard deviation
          1/(.A*sqrt(.B)).  IF .B is an integer it is  obtained by
          .B basic drawings (uniform in [0,1)) as:

               -(log(.U1) + ... + log(.Ub)) / (.A + .B)

          If .B is not an  integer the above term is  formed using
          FIX .B drawings, and the following term added:

                - (.B - FIX .B) * log(.U) / (.A * .B)

          i.e. another drawing is required.  Note that both .A and
          .B  should be  greater than  0.  The  B  provided should
          always  be in  floating point  format even  if it  is an
          integer.

     DISCRETE(*A,N,*U)

          A = real vector, cumulative distribution (almost).
          N = integer, maximum index of A (indexed 0 through .N).

          The value of DISCRETE is an integer in  [0,.N+1] defined
          by being  the least integer  i such that  .A[i] >  .U (U
          uniform  in   [0,1)).   If   the  inequality   is  never
          satisfied, .N+1 is returned.

     LINEAR(*A,*B,N,*U)

          A = real vector, ordinates of cumulative distribution.
          B = real vector, abscissae of cumulative distribution.
          N = integer, maximum index of A and B.

          A  and  B  constitute  a  non-equidistant  table  for  a
          cumulative  distribution  function  f.   I.e.   .A[i]  =
          f(.B[i]) for all i in [0,.N].  .A[0] should be  0.0, and
          .A[.N]  should  be  1.0.  For  all  i  in  [0,.N-1], the
          following should hold; .A[i+1] geq .A[i] and .B[i+1] geq
          .B[i].  The values of  LINEAR are real, obtained  by one
          basic  drawing  uniform  in  [0,1)  and  inverse  linear
          interpolation in the table.
BLILIB.DOC                       17                  January 25, 1978

                           ROUTINE SUMMARY

DATE AND TIME CONVERSION
  DATE()                           COMPLEX MESSAGE OUTPUT
  TIME()                             MSGSCAN(CHNL,PARMS,PATTERNPTR)
  DAYOFWEEK(VAL)
  PDATE(CHNL,VAL)                  FILE SELECTION
  PTIME(CHNL,VAL)                    WANTREAD(*CHNL,MODE,BUFS,PTR,
                                               *BLOCK,*PPN)
FLOATING POINT OUTPUT                WANTWRITE(*CHNL,MODE,BUFS,PTR,
  FLOUT(CHNL,VAL,BEFORE,AFTER)                 *BLOCK,WARN)
  EFLOUT(CHNL,VAL,BEFORE,AFTER)
  SEFLOUT(CHNL,VAL,BEFORE,AFTER,   DYNAMIC SPACE ALLOCATION
            SCALE)                   INITSPACE()
                                     GETSPACE(SIZE)
GENERAL NUMBER OUTPUT                RELSPACE(ADDRESS,SIZE)
  OUTNUM(CHNL,VAL,BASE,WIDTH)        GARBAGECOLLECT()

NUMBER INPUT                       SCIENTIFIC SUBROUTINE PACKAGE
  NUMSCAN(*PTR,BASE,TOG)             SQRT(X)
                                     SIN(X) and COS(X)
FILE NAME SCANNING                   LOG(X)
  FILESCAN(*PTR,*BLOCK)              EXP(X)

PPN CONVERSION                     PSEUDO-TELETYPE I/O
  CMUDEC(PTR)                        GETPTY(*CHNL,*PTYNUM)
  DECCMU(PPN,*PTR)                   PTYLOG(CHNL,*JOBNUM,*PPN,*PASS)
                                     PTYATT(CHNL,JOBNUM,*PPN,*PASS)
I/O                                  PTYDET(CHNL)
  GETCHAN()                          PTYKJOB(CHNL)
  BUFFERS(CHNL,NUMBER,INPUT,WHERE)   PTYRELEASE(CHNL)
  OPEN(CHNL,STATUS,LDEV,BUFS)        PTYMONMOD(CHNL)
  LOOKUP(CHNL,*LOOKUPBLOCK)          INITPTYS()
  ENTER(CHNL,*ENTERBLOCK)            PTYOC(CHNL,CHAR)
  READ(CHNL)                         PTYOSTR(CHNL,*STR)
  WRITE(CHNL,CHAR)                   PTYINC(CHNL)
  WRITEMSG(CHNL,PTR)                 PTYINW(CHNL,MAXWAIT)
  PURGEOUT(CHNL)                     PTYWAIT(CHNL,MAXWAIT,*STR)
  CLOSE(CHNL)                        PTYCLRBUF(CHNL)
  CLOSEF(CHNL,BITS)                  PTYRESPONSE(CHNL)
  OUTMSG(TEXT)                       PTYHIBER(CHNL,MAXWAIT)
  BUFHDR(CHAN)
                                   SPOOLING
MORE I/O                             SPOOL(*BLOCK,COPIES,DELETE)
  LREAD(CHNL)
  READLINE(CHNL,*BUFFER,           RANDOM NUMBER GENERATORS
            *LINENUMBER)             RANDINT(A,B,*U)
  RENAME(CHNL,*RENAMEBLOCK)          UNIFORM(A,B,*U)
  PURGEOUT(CHNL)                     NORMAL(A,B,*U)
  CLOSEF(CHNL,BITS)                  FASTNORMAL(A,B,*U)
  DUMPIN(CHNL,LISTADDRESS)           NEGEXP(A,*U)
  DUMPOUT(CHNL,LISTADDRESS)          POISSON(A,*U)
  GETSTS(CHNL)                       ERLANG(A,B,*U)
  SETSTS(CHNL,BITS)                  DISCRETE(*A,N,*U)
  USETO(CHNL,BLKNUM)                 LINEAR(*A,*B,N,*U)
  USETI(CHNL,BLKNUM)